package com.stockz.indicator.volume;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.stockz.core.model.Bar;
import com.stockz.core.util.BarUtil.BarValueType;
import com.stockz.core.util.BarUtil;
import com.stockz.core.util.ListUtil;
import com.stockz.indicator.Indicator;
import com.stockz.ui.swing.charting.util.MathUtil;

@SuppressWarnings("unused")
public class VolumeIndicator implements  Indicator<VolumeIndicatorConfiguration> {

	private VolumeIndicatorConfiguration volumeIndicatorConfiguration 
	 = new VolumeIndicatorConfiguration();
	private BarValueType barValueType = BarValueType.VOLUME;
	
	
	
	@Override
	public double getValue(List<Bar> barList) {
		throw new UnsupportedOperationException();
	}

	@Override
	public double[] getValues(List<Bar> barList) {
		throw new UnsupportedOperationException();
	}
	
	
	public List<PriceRange> getPriceRangeList(List<Bar> barList){

		if(barList == null || barList.size() == 0){
			return null;
		}
		
		double min = MathUtil.min(ListUtil.convert(barList, BarValueType.LOW));
		double max = MathUtil.max(ListUtil.convert(barList, BarValueType.HIGH));
		List<PriceRange> priceRangeList = preparePriceRangeListUsingDivisions(min,max);
		for(PriceRange priceRange : priceRangeList){
			double valueSum = 0;
			for(int i = 1; i <= barList.size(); i++){
				Bar bar = barList.get(i-1);
				if(bar.getClose() < priceRange.getUpperLimit()
						&& bar.getClose() >= priceRange.getLowerLimit()){
					if(volumeIndicatorConfiguration.isWeighed()){
						valueSum += (BarUtil.getValue(bar,getBarValueType())/i);
					}else{
						valueSum += (BarUtil.getValue(bar,getBarValueType()));
					}
				}
			}
			priceRange.setValue(valueSum);
		}
		return priceRangeList;
	}
	
	private List<PriceRange> preparePriceRangeList(double[] valueArray){
		double max = MathUtil.max(valueArray);
		double min = MathUtil.min(valueArray);
		return preparePriceRangeListUsingDivisions(min,max);
	}
	
	
	private List<PriceRange> preparePriceRangeListUsingPercentage(double min, double max){
		List<PriceRange> priceRangeList = new ArrayList<PriceRange>();
		while(max > min){
			double upperLimit = min*((volumeIndicatorConfiguration.getPercentage()+100)/100);
			PriceRange priceRange = new PriceRange(upperLimit,min);
			priceRangeList.add(priceRange);
			min = upperLimit;
		}
		return priceRangeList;
	}
	
	private List<PriceRange> preparePriceRangeListUsingDivisions(double min, double max){
		List<PriceRange> priceRangeList = new ArrayList<PriceRange>(volumeIndicatorConfiguration.getDevisions());
		double range = (max - min)/volumeIndicatorConfiguration.getDevisions();
		for(int i = 0; i < volumeIndicatorConfiguration.getDevisions(); i++){
			PriceRange priceRange = new PriceRange((i+1)*range+min,i*range+min);
			priceRangeList.add(priceRange);
		}
		return priceRangeList;
	}
	
	@Override
	public VolumeIndicatorConfiguration getIndicatorConfiguration() {
		return volumeIndicatorConfiguration;
	}

	public BarValueType getBarValueType() {
		return BarValueType.VOLUME;
	}

	public void setBarValueType(BarValueType barValueType) {
		this.barValueType = barValueType;
	}
	
}
